// 条件类型

// 这里呢我们定义了一个类型别名 TypeName 它呢是一种条件类型，而且是一种条件类型的嵌套，
// 它呢会依次判断 T 的类型然后会返回不同的字符串
type TypeName<T> = T extends string
  ? "string"
  : T extends number
  ? "number"
  : T extends boolean
  ? "boolean"
  : T extends undefined
  ? "undefined"
  : T extends Function
  ? "function"
  : "object";

type T1 = TypeName<string>;
type T2 = TypeName<string[]>;

type T3 = TypeName<string | string[]>;

type Diff<T, U> = T extends U ? never : T;

type T4 = Diff<"a" | "b" | "c", "a" | "e">;
// Diff<"a", "a" | "e"> | Diff<"b", "a" | "e"> | Diff<"c", "a" | "e"> Diff呢会被拆解成这个样子
// never | "b" | "c"
// "b" | "c"

type NotNull<T> = Diff<T, undefined | null>;

type TS = NotNull<string | number | undefined | null>;

// Exclude<T, U>
// NonNullable<T>
// Extract<T, U>

type T6 = Extract<"a" | "b" | "c", "a" | "e">;

// ReturnType<T>
type T7 = ReturnType<() => string>;
